unit uUtils;

interface

uses SysUtils, Windows, Classes, Consts, Forms, ShellAPI;

//Execute an external application and wait for its end.
//    ExcuteFile: external application file name.
//    Parameters: parameters for external application
function ExecAndWait(const ExecuteFile, ParamString: string): boolean;

//Get last modified time of a file
function GetFileLastModified(const fileName: string): TDateTime;

//this function reads the file ressource of "FileName" and returns the version
// number as formatted text. in "Fmt" you can use at most four integer values.
// http://www.martinstoeckli.ch/delphi/delphi.html#AppVersion
function GetFileVersion(const FileName: string): string;

implementation

function ExecAndWait(const ExecuteFile, ParamString: string): boolean;
var
  SEInfo: TShellExecuteInfo;
  ExitCode: DWORD;
begin
  FillChar(SEInfo, SizeOf(SEInfo), 0);
  SEInfo.cbSize := SizeOf(TShellExecuteInfo);
  with SEInfo do begin
    fMask := SEE_MASK_NOCLOSEPROCESS;
    Wnd := Application.Handle;
    lpFile := PChar(ExecuteFile);
    lpParameters := PChar(ParamString);
    nShow := SW_HIDE;
  end;

  if ShellExecuteEx(@SEInfo) then
  begin
    repeat
      Application.ProcessMessages;
      GetExitCodeProcess(SEInfo.hProcess, ExitCode);
    until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
    Result := True;
  end
  else
    Result := False;
end;

function GetFileLastModified(const fileName: string): TDateTime;
var
  DosFileTime: integer;
begin
  DosFileTime := FileAge(fileName);
  if DosFileTime <> -1 then
    result := FileDateToDateTime(DosFileTime)
  else
      //File not exist
    result := now();
end;

function GetFileVersion(const FileName: string): string;
var
  iBufferSize: DWORD;
  iDummy: DWORD;
  pBuffer: Pointer;
  pFileInfo: Pointer;
  iVer: array[1..4] of Word;
const
  versionFormat: string = '%d.%d.%d.%d';
begin
  // set default value
  Result := '';
  // get size of version info (0 if no version info exists)
  iBufferSize := GetFileVersionInfoSize(PChar(FileName), iDummy);
  if (iBufferSize > 0) then
  begin
    GetMem(pBuffer, iBufferSize);
    try
    // get fixed file info
      GetFileVersionInfo(PChar(FileName), 0, iBufferSize, pBuffer);
      VerQueryValue(pBuffer, '\', pFileInfo, iDummy);
    // read version blocks
      iVer[1] := HiWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionMS);
      iVer[2] := LoWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionMS);
      iVer[3] := HiWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionLS);
      iVer[4] := LoWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionLS);
    finally
      FreeMem(pBuffer);
    end;
    // versionFormat result string
    Result := Format(versionFormat, [iVer[1], iVer[2], iVer[3], iVer[4]]);
  end;
end;


end.
